#pragma once
#include "base\Controller.h"
#include "EventManager.h"
#include "utils\mtrand.h"
#include "nodes\DynamicSpriteNode.h"
#include "src\effects\BulletSystem.h"
#include "src\actors\Ship.h"
#include "HUD.h"
#include "src\actors\Meteoroids.h"
#include "src\actors\Asteroids.h"
#include "src\actors\FloatingParticles.h"
#include "nodes\SpriteNode.h"
#include "collision\CollisionDetector.h"
#include "src\actors\Swimmer.h"
#include <ui\UI.h>
#include <particles\ParticleSystem.h>
#include "addons\SpriteCounter.h"
#include "src\static\NewHUD.h"

class AstroGame {

public:
	AstroGame();
	~AstroGame();
	Ship& player() {
		return *m_Player;
	}
	BulletSystem& bullets() {
		return *m_Bullets;
	}
	ds::ParticleManager* particles() {
		return m_ParticleManager;
	}
	FloatingParticles& floatingParticles() {
		return *m_Particles;
	}
	Asteroids& asteroids() {
		return *m_Asteroids;
	}
	Meteoroids& meteoroids() {
		return *m_Meteoroids;
	}
	Swimmer& swimmer() {
		return *m_Swimmer;
	}
	/*
	HUD& hud() {
		return *m_HUD;
	}
	*/
	NewHUD& hud() {
		return *m_HUD;
	}
	ds::SpriteCounter* levelInfo() {
		return m_LevelInfo;
	}
	int getLevel() {
		return m_Level;
	}
	void incLevel() {
		++m_Level;
	}
	ds::DynamicSpriteNode* enemies() {
		return m_EnemySprites;
	}
	ds::SpriteNode* basicSprites() {
		return m_SpriteNode;
	}
private:
	Ship* m_Player;
	BulletSystem* m_Bullets;
	ds::ParticleManager* m_ParticleManager;
	FloatingParticles* m_Particles;
	Asteroids* m_Asteroids;
	Meteoroids* m_Meteoroids;
	Swimmer* m_Swimmer;
	//HUD* m_HUD;
	NewHUD* m_HUD;
	ds::SpriteCounter* m_LevelInfo;
	int m_Level;
	ds::DynamicSpriteNode* m_Sprites;
	ds::DynamicSpriteNode* m_EnemySprites;
	ds::SpriteNode* m_SpriteNode;
};

class GameCore : public ds::EventHandler , ds::CollisionHandler , public ds::IUIEventListener {

enum GameMode {
	GM_LEVEL_INFO,GM_RUNNING,GM_OVER
};

public:
	GameCore(void);
	~GameCore(void);
	void loadContent(ds::ResManager& resourceManager);
	//	
	void process(ds::EventBuffer& buffer );
	//
	void processBuffer(ds::CollisionBuffer& buffer);	
	void startWave();
	void start();
	void setAutofire(bool autoFire) {
		m_AutoFire = autoFire;
		m_Engine->floatingParticles().setMagneticMode(!autoFire);
	}
	void setMagnetic(bool m) {
		if ( m_Mode == GM_RUNNING ) {
			m_Magnetic = m;
			m_Engine->player().setMagnetic(m);
		}
	}
	void stop() {
		setMode(GM_OVER);
	}
	void setFireMode(FireMode fireMode) {
		m_Engine->bullets().setFireMode(fireMode);		
	}
	void usePowerup(const char* name);
	void onUIEvent(const ds::IUIEvent& event);
	AstroGame* engine() {
		return m_Engine;
	}
private:	
	// methods
	void setMode(GameMode mode);
	void startRingExplosion(const ds::Vec2& center,float radius);
	AstroGame* m_Engine;
	bool m_AutoFire;
	GameMode m_Mode;
	bool m_Magnetic;
	ds::ActionGroup* group;
};

